#define MSDHCP_C
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <string.h> 
#include <errno.h> 
//set start flag
#include <libmscommon/mscommon.h>
#include <libmscommon/msnetwork.h>
#include <libmscommon/mscjson.h>
#include <libmscommon/msmd.h>
#include <libmslog/mslog.h>
#include "msweb.h"
#include "msdhcp.h"
#define FLAG "DHCP"

#define msifconfig_endline			LINE_END
#define msidhcp_conffile_default		"/etc/default/isc-dhcp-server"
#define msidhcp_conffile_dhcpd		"/etc/dhcp/dhcpd.conf"
#define msdb_msdhcp  				"/etc/mscore/db/msdb_msdhcp.db"


static MSDHCPContext msdhcpctt_db;
static ms_void msdhcp_innerapi_writeDB(ms_void)
{
	cJSON * json_root = cJSON_CreateObject();
	if(ms_null == json_root){
		ms_errNoret("cJSON_CreateObject failed");
	}
	msdhcp_api_buildJsonInfo(json_root);
	char * json_string = cJSON_Print(json_root);
	cJSON_Delete(json_root);
	if(ms_null==json_string){
		ms_errNoret("cJSON_Print failed");
	}
	msmd_api_writeProtect(msdb_msdhcp, json_string, strlen(json_string));
ms_end:	
	free(json_string);
}

static ms_s08 msdhcp_innerapi_readDB(ms_void)
{
	ms_byte json_buf[40960]={0};
	if(0>msmd_api_read2(msdb_msdhcp, json_buf, sizeof(json_buf))){
		msdhcp_innerapi_writeDB();
		ms_errRet(-1,"msmd_api_read2 faild");
	}
	cJSON *jsonroot = cJSON_Parse(json_buf);
	if(!jsonroot) {
		ms_errRet(-1,"cJSON_Parse:get root faild");
	}
	msdhcp_api_parseJsonInfo(jsonroot,&msdhcpctt_db);
	return 0;
}


ms_bool msdhcp_api_init(ms_void)
{
	ms_stru0(&msdhcpctt_db, MSDHCPContext);
	msdhcp_innerapi_readDB();
	//msdhcp_api_set(&msdhcpctt_db,ms_null);
	msdhcpctt_db.flag_init=ms_true;
	return ms_true;
}
ms_s08 msdhcp_api_set(MSDHCPContext* ms_in pDhcpCtt,ms_u08 * ms_out  outStr)
{
/*/etc/default/isc-dhcp-server*/
	ms_byte  buf[1024]={0};
	if(ms_false==pDhcpCtt->flag_enable){
		ms_byte cmd[256]={0};
		ms_strcpy(cmd, "/lib/systemd/systemd-sysv-install disable isc-dhcp-server");
		if(ms_false==ms_cmdRet(cmd)){
			if(ms_null!=outStr){ms_sprintfs(outStr, "%s failed",cmd);}
			ms_errRet(-3, "%s failed",cmd);
		}
		ms_strcpy(cmd, "service  isc-dhcp-server stop");
		if(ms_false==ms_cmdRet(cmd)){
			if(ms_null!=outStr){ms_sprintfs(outStr, "%s failed",cmd);}
			ms_errRet(-3, "%s failed",cmd);
		}
		ms_strcpy(cmd, " service isc-dhcp-server status | grep \"inactive (dead)\"");
		if(ms_false==ms_cmdIsGrep(cmd)){
			if(ms_null!=outStr){ms_sprintfs(outStr, "%s failed",cmd);}
			ms_errRet(-3, "%s failed",cmd);
		}
		msdhcpctt_db.flag_enable=ms_false;
	}else{
		if(ms_buflen(pDhcpCtt->option_routers)>0){
			ms_sprintfs(buf, "INTERFACESv4=\"%s\"",pDhcpCtt->interfaces);
		}else{
			if(ms_null!=outStr){ms_sprintfs(outStr, "Must set interfaces");}
			ms_errRet(-1,"Must set interfaces");
		}
		msmd_api_writeProtect(msidhcp_conffile_default, buf, ms_buflen(buf));
	/*/etc/dhcp/dhcpd.conf   ,If /etc/ltsp/dhcpd.conf exists, that will be used as configuration file instead of this file*/
		ms_buf0(buf);
		ms_byte  tbuf[1024]={0};

		ms_strcats(tbuf,buf, "default-lease-time 600;\r\n");
		ms_strcats(tbuf,buf, "max-lease-time 7200;\r\n");
		ms_strcats(tbuf,buf, "ddns-update-style none;\r\n");

		if(0==ms_buflen(pDhcpCtt->netmask)||0==ms_buflen(pDhcpCtt->iprange)||0==ms_buflen(pDhcpCtt->ipaddr)){
			if(ms_null!=outStr){ms_sprintfs(outStr, "Must set netmask,iprange,ipaddr");}
			ms_errRet(-1,"Must set netmask,iprange,ipaddr");
		}
		ms_byte subnet[16]={0};
		msnet_api_subnet(pDhcpCtt->ipaddr, pDhcpCtt->netmask, subnet);
		ms_strcats(tbuf,buf, "subnet %s netmask %s {\r\n",subnet,pDhcpCtt->netmask);
		ms_strcats(tbuf,buf, "    range %s;\r\n",pDhcpCtt->iprange);
		if(ms_buflen(pDhcpCtt->option_routers)>0){
			ms_strcats(tbuf,buf, "    option routers %s;\r\n",pDhcpCtt->option_routers);
		}
		if(ms_buflen(pDhcpCtt->option_domainname)>0){
			ms_strcats(tbuf,buf, "    option domain-name \"%s\";\r\n",pDhcpCtt->option_domainname);
		}
		if(ms_buflen(pDhcpCtt->option_domainname_servers)>0){
			ms_strcats(tbuf,buf, "    option domain-name-servers %s;\r\n",pDhcpCtt->option_domainname_servers);
		}
		if(pDhcpCtt->lease_time_default>0){
			ms_strcats(tbuf,buf, "    default-lease-time %d;\r\n",pDhcpCtt->lease_time_default);
		}
		if(pDhcpCtt->lease_time_max>0){
			ms_strcats(tbuf,buf, "    max-lease-time %d;\r\n",pDhcpCtt->lease_time_max);
		}
		ms_strcats(tbuf,buf, "}");
		msmd_api_writeProtect(msidhcp_conffile_dhcpd, buf, ms_buflen(buf));

		ms_byte cmd[256]={0};
#if 0		
		ms_sprintfs(cmd, "ifconfig  %s:10  %s  netmask %s  ",pDhcpCtt->interfaces,pDhcpCtt->ipaddr,pDhcpCtt->netmask);
		if(ms_false==ms_cmdRet(cmd)){
			if(ms_null!=outStr){ms_sprintfs(outStr, "%s failed",cmd);}
			ms_errRet(-2, "%s failed",cmd);
		}
#endif
		ms_strcpy(cmd, "/lib/systemd/systemd-sysv-install enable isc-dhcp-server");
		if(ms_false==ms_cmdRet(cmd)){
			if(ms_null!=outStr){ms_sprintfs(outStr, "%s failed",cmd);}
			ms_errRet(-2, "%s failed",cmd);
		}
		ms_strcpy(cmd, "service  isc-dhcp-server restart");
		if(ms_false==ms_cmdRet(cmd)){
			if(ms_null!=outStr){ms_sprintfs(outStr, "%s failed",cmd);}
			ms_errRet(-2, "%s failed",cmd);
		}
		ms_strcpy(cmd, " service isc-dhcp-server status | grep \"active (running)\"");
		if(ms_false==ms_cmdIsGrep(cmd)){
			if(ms_null!=outStr){ms_sprintfs(outStr, "%s failed",cmd);}
			ms_errRet(-2, "%s failed",cmd);
		}
		ms_memcpy(&msdhcpctt_db, pDhcpCtt, ms_bufsize(MSDHCPContext));
		msdhcpctt_db.flag_init=ms_true;
	}	
	msdhcp_innerapi_writeDB();
	return 0;
}

ms_void msdhcp_api_buildJsonInfo(ms_void * jsnode_item)
{
	cJSON * jsnode=(cJSON *)jsnode_item;
	cJSON * json_msdhcp_info=cJSON_CreateObject();
	cJSON_AddItemToObject(jsnode, "msdhcp_info", json_msdhcp_info);
	ms_byte cmd[256]={0};
	ms_pbyte pstatus=ms_null;
	if(ms_false==msmd_api_isInstall("isc-dhcp-server")){
		pstatus="no install";
	}else{
		ms_strcpy(cmd, " service isc-dhcp-server status | grep \"active (running)\"");
		pstatus=(ms_false==ms_cmdIsGrep(cmd)) ? "dead" : "running";
	}
	MSJSON_BUILD_STRING(json_msdhcp_info, "status",pstatus) ;
	MSJSON_BUILD_INT(json_msdhcp_info, "flag_enable",msdhcpctt_db.flag_enable) ;
	MSJSON_BUILD_STRING(json_msdhcp_info, "interfaces",msdhcpctt_db.interfaces) ;
	MSJSON_BUILD_INT(json_msdhcp_info, "lease_time_default",msdhcpctt_db.lease_time_default) ;
	MSJSON_BUILD_INT(json_msdhcp_info, "lease_time_max",msdhcpctt_db.lease_time_max) ;
	MSJSON_BUILD_STRING(json_msdhcp_info, "ipaddr",msdhcpctt_db.ipaddr) ;
	MSJSON_BUILD_STRING(json_msdhcp_info, "netmask",msdhcpctt_db.netmask) ;
	MSJSON_BUILD_STRING(json_msdhcp_info, "iprange",msdhcpctt_db.iprange) ;
	MSJSON_BUILD_STRING(json_msdhcp_info, "option_routers",msdhcpctt_db.option_routers) ;
	MSJSON_BUILD_STRING(json_msdhcp_info, "option_subnetmask",msdhcpctt_db.option_subnetmask) ;
	MSJSON_BUILD_STRING(json_msdhcp_info, "option_domainname",msdhcpctt_db.option_domainname) ;
	MSJSON_BUILD_STRING(json_msdhcp_info, "option_domainname_servers",msdhcpctt_db.option_domainname_servers) ;
}

ms_void msdhcp_api_parseJsonInfo(ms_void * jsRoot,MSDHCPContext *pDhcpCtt)
{
	ms_string ethmod[128]={ethnmode_string};
	cJSON *json_msdhcp_info=cJSON_GetObjectItem(jsRoot,"msdhcp_info");
	cJSON *js_item=ms_null;
	MSJSON_PARSE_INT_DEFALUT(js_item,json_msdhcp_info, "flag_enable",pDhcpCtt->flag_enable,-1) ;
	MSJSON_PARSE_STRING(js_item,json_msdhcp_info, "interfaces",pDhcpCtt->interfaces) ;
	MSJSON_PARSE_INT(js_item,json_msdhcp_info, "lease_time_default",pDhcpCtt->lease_time_default) ;
	MSJSON_PARSE_INT(js_item,json_msdhcp_info, "lease_time_max",pDhcpCtt->lease_time_max) ;
	MSJSON_PARSE_STRING(js_item,json_msdhcp_info, "ipaddr",pDhcpCtt->ipaddr) ;
	MSJSON_PARSE_STRING(js_item,json_msdhcp_info, "netmask",pDhcpCtt->netmask) ;
	MSJSON_PARSE_STRING(js_item,json_msdhcp_info, "iprange",pDhcpCtt->iprange) ;
	MSJSON_PARSE_STRING(js_item,json_msdhcp_info, "option_routers",pDhcpCtt->option_routers) ;
	MSJSON_PARSE_STRING(js_item,json_msdhcp_info, "option_subnetmask",pDhcpCtt->option_subnetmask) ;
	MSJSON_PARSE_STRING(js_item,json_msdhcp_info, "option_domainname",pDhcpCtt->option_domainname) ;
	MSJSON_PARSE_STRING(js_item,json_msdhcp_info, "option_domainname_servers",pDhcpCtt->option_domainname_servers) ;	
}

ms_void msdhcp_api_webinfo(ms_string ms_out outBuf)
{			
	ms_byte tempbuf[2048]={0};
	ms_byte info[2048]={0};
	ms_s32 len=0;
	if(ms_false==msdhcpctt_db.flag_init){
		ms_strcats(tempbuf,outBuf,"<h4 ""style=\"color:black;\""">%s</h4>","Wait init...") ;
	}else{
		ms_byte cmd[256]={0};
		ms_pbyte pstatus=ms_null;
		if(ms_false==msmd_api_isInstall("isc-dhcp-server")){
			pstatus="no install";
		}else{
			ms_strcpy(cmd, " service isc-dhcp-server status | grep \"active (running)\"");
			pstatus=(ms_false==ms_cmdIsGrep(cmd)) ? "dead" : "running";
		}
		ms_strcats(tempbuf,outBuf,"<tr>");
		ms_strcats(tempbuf,outBuf,
			"<ul "MSWEB_FONT_STYLE">"
			"<li>service isc-dhcp-server status:%s</li>"
			"<li>flag_enable=%d</li>"
			"<li>interfaces=%s</li>"   
			"<li>lease_time_default=%d</li>"
			"<li>lease_time_max=%d</li>"   
			"<li>ipaddr=<%s/li>"
			"<li>netmask=%s</li>"   
			"<li>iprange=%s</li>"
			"<li>option_routers=%s</li>"   
			"<li>option_subnetmask=<%s/li>"
			"<li>option_domainname=%s</li>"   
			"<li>option_domainname_servers=%s</li>"   
			"</ul>",  
			pstatus,
			msdhcpctt_db.flag_enable, 
			msdhcpctt_db.interfaces,
			msdhcpctt_db.lease_time_default,
			msdhcpctt_db.lease_time_max,
			msdhcpctt_db.ipaddr,
			msdhcpctt_db.netmask,
			msdhcpctt_db.iprange,
			msdhcpctt_db.option_routers,
			msdhcpctt_db.option_subnetmask,
			msdhcpctt_db.option_domainname,
			msdhcpctt_db.option_domainname_servers) ;
		ms_strcats(tempbuf,outBuf,"</tr>");

	}
	ms_strcats(tempbuf,outBuf,	
			"</tbody>"
		);			
	ms_strcats(tempbuf,outBuf,	
		"</table>"
		);

	
}

#undef MSDHCP_C
